-[ 0x07 ]--------------------------------------------------------------------
-[ SX1-Primera parte ]-------------------------------------------------------
-[ by FCA00000 ]-----------------------------------------------------SET-32--

Diario de un SX1-ero

Proverbio: "De lo que veas, cree solo el 50%. De lo que escuches, el 10%. De lo
que oigas, el 2%."

27/08 *********** Sabado ***********
Por una casualidad de esas que da la vida, he conseguido varios Siemens-SX1. No
uno ni 2, sino 7 !
Todos tienen cable USB, bateria, y auriculares. Algunos tienen la bateria 
cargada, y parecen funcionar.
Los he puesto a cargar antes de salir a dar una vuelta.

Cuando vuelvo, 5 horas mas tarde, compruebo que todos funcionan. Sueno 
reparador.

28/08 *********** Domingo ***********
Como soy un antiguo forofo de los telefonos Siemens, he aprendido a modificar 
el software que tienen.
Esto me permite hacer cambios (pequenos), pero lo realmente entretenido es 
aprender, aunque no tenga utilidad.
Hasta ahora he trabajado con el modelo C35 y S45, que incorporan un procesador 
C166. Segun creo, el SX1 es distinto.
Pero lo bueno es que tengo 5 tarjetas SIM para usar, y muchas ganas de probar 
lo que se puede hacer.

He visto que el SX1 incorpora unos cuantos programas. Los graficos son bastante
potentes (para ser un movil, claro)

Sorpresa! Todos llevan una tarjeta de memoria de 128 Mb. Uno de ellos ademas 
contiene canciones. No consigo hacerlas sonar. Al parecer necesito un programa 
para ello.

He conseguido conectarlos por infrarrojos. El cable USB veo que funciona porque
aparece un icono en el movil, pero Windows me pide un driver para el SX1.
Manana buscare en Internet desde el trabajo, puesto que en casa no tengo 
conexion.

29/08 *********** Lunes ***********
Me he pasado el dia surfeando. He conseguido unos 50 programas, la mayoria 
juegos.
Tambien he obtenido mucha informacion:
Al parecer lleva un Sistema Operativo llamado Symbian, al igual que los moviles
Nokia de penultima generacion.
Esto permite que los juegos sirvan para ambos, abriendo un mercado bastante 
amplio.
Uno de los modelos de Nokia se llama N-Gage, orientado sobre todo para juegos.
Hoy no tengo tiempo de probar nada porque me voy a cenar fuera.

30/08 *********** Martes ***********
Mas investigacion: este cacharrito es mas grande de lo que pensaba.
Dentro de un sistema OT433 lleva un microprocesador ARM952 a 120Mhz.
La memoria es RAM de 16Mb, y los programas estan en 3 zonas:
-ROM, para el sistema operativo. Ocupa 16 Mb
-flash, para programas y datos "temporales". Usa 4 Mb
-tarjeta extraible de memoria. En mi caso son de 128 Mb
Ademas tiene USB, bluetooth, infrarrojos, camara, sonido estereo, radio, y una 
bateria que parece durar poco.
Ah, y las teclas estan en unas posiciones muy raras. Por otro lado yo tengo un 
S45 con el que estoy muy contento.
El S45 para llamar, y el SX1 para juguetear.

He probado alguno de los juegos. Son aceptablemente rapidos, y ocupan poco 
(excepto el Doom)
Tambien he conseguido algunas utilidades imprescindibles:
-FExplorer, para ver todos los archivos. Rapido y efectivo. 
 Copia/mueve/renombra/borra/crea archivos y directorios.
-TaskSpy, para ver los procesos y matar a aquellos que se quedan colgados.
-HView, un editor hexadecimal.
-Opera, navegador web. No pienso conectarme a Internet desde el movil, pero me 
 vendra bien para leer libros HTML en el autobus.
-Spectrian, emulador del ZX-Spectrum. Realmente impresionante lo bien que esta 
 hecho.
Ademas de las que vienen incluidas en el sistema operativo:
-Manager, para ver las aplicaciones instaladas, y poder desinstalarlas.
-File Manager, otro navegador de archivos. Permite copiar carpetas completas.
-Notepad, Calculadora, reloj, agenda, ...

31/08 *********** Miercoles ***********
Hoy he bajado de la red otros programas. Entre ellos un driver USB.
Ahora windows esta mas contento, pero sigo sin poder acceder al movil. Yo 
pensaba que apareceria como otra unidad de disco, pero nada de nada.
Todo lo que he conseguido es que en el hyperterminal me aparece el puerto COM4 
llamado USBSER000, pero no responde a los comandos AT.

Mas tarde encontuentro que si arranco la aplicacion de FAX y la conecto por 
infrarrojos, algunos comandos AT funcionan satisfactoriamente.

Poniendo la configuracion a velocidad de 19200 baudios, me aparece basura en el
hyperterminal. Son unos 60 caracteres en 10 rafagas cada 2 segundos. Podria ser
un protocolo PPP.
~ }#A!}!}!} }4}%}&yi||}"}&} } } } }'}"}(
}"}4~~ }#
A!}!}!} }4}%}&}1cya}"}&} } } }
 }'}"}(}":}9~~ }#A!}%}"} }$Y(~~ }#A!}!}!} }
4}%}&|eR3}"}&} } } } }'}"}(}"|H~~ }#A
!}!}!} }4}%}&|eR3}"}&} } } } }'}"}(}"|H~~ }#A!}%
}"} }$Y(~~ }#A!}!}!} }4}%}&z/on}
"}&} } } } }'}"}(}"ap~~ }#A!}!}!} }4}%}&|/on
}"}&} } } } }'}"}(}"ap~~ }#A!}%}"} }
$Y(~~ }#A!}!}!} }4}%}&OA0|}"}&} } } } }'

Tambien me aparece configurado como modem: Siemens SX1 USB modem a 230400 
baudios. Pero aqui no responde nada.
Arranco el Portmon, que es un sniffer del puerto serie.
El trafico que veo es lo mismo que con el hyperterminal. Ademas veo que el 
puerto de infrarrojos tambien recibe la misma basura.
Lo bueno es que Windows, con la aplicacion irftp, es capaz de transferir 
programas desde el PC hacia el movil.
Eso quiere decir que reconoce el protocolo OFTP para transferencia de ficheros.
Quizas necesite otro programa especial para usar comandos AT-Hayes.

01/09 *********** Jueves ***********
He encontrado un foro en castellano sobre el SX1. Se llama 
www.comunidad-siemens.com (en adelante, CS) y la gente sabe bastante.
No he encontrado referencias a programar el movil, pero he aprendido muchas 
cosas:
-es posible actualizar el Sistema Operativo. Yo tengo la version 10, pero ellos
 usan la "15.2 IBERIA". Me la he descargado.
-tambien se pueden hacer parches para cambiar ciertas cosas.
-los cambios parecen ser en los dibujos, melodias, salvapantallas, ... aunque
 espero que tambien haya parches "funcionales".
-Para actualizar el movil hay que pulsar el joystick hacia abajo, esperar un
 segundo, y a la vez pulsar la tecla de encendido. La actualizacion se hace por
 USB. Ya veremos si me funciona.
-Usar el movil para transferir datos con el cable USB parece ser problematico.
 Necesito el programa MPM (Mobile Phone Manager) desde la web de Siemens,
 ademas de una actualizacion para el SX1. Ya los tengo.
-He hecho mi primera pregunta en el foro. En 2 horas no ha respondido nadie.
 Esperare a manana.
-Efectivamente hay muchos juegos. Es mas: se puede emular un GameBoy, y otras
 consolas mas. Como yo no soy muy jugador, me da igual.
-Se pueden hacer programas para Symbian. Hay algunos otros foros dedicados a
 ello, por ejemplo www.allaboutsymbian.com
-Hay unos rusos que le han sacado las tripas: www.oslik.ru pero mi nivel de
 entender ruso es nulo. Babelfish es mi amigo.

Aunque tengo ganas de probar los programas que me he bajado, hoy hace muy buen 
tiempo, y hemos decidido salir de terrazas para tomar unas tapas.

02/09 *********** Viernes ***********
Como he desperdiciado bastante tiempo en los ultimos dias, hoy tengo un poco de
trabajo atrasado. Musica de Strauss para aislarme del mundo y poder acabar la 
documentacion que necesita el equipo de Weblogic. Hay reunion el proximo Lunes.

03/09 *********** Sabado ***********
Cargo en el ordenador el programa FW15.2[CS].exe de actualizacion del movil, 
que tiene la bateria llena, por supuesto.
Con gran excitacion pulso el joystick y la tecla de encendido, y en la pantalla
me dice algo asi como "Listo para actualizacion de software".
El programa empieza a hacer su trabajo y observo satisfecho que la barra de 
progreso se mueve, indicando que el firmware se esta actualizando.
Al cabo de 15 minutos termina, y el movil se apaga.
Lo enciendo de nuevo, y ahora usa unos graficos diferentes. Parece que lo he 
hecho bien.
Pulsando *#06# me dice el IMEI, y el boton "Info" arranca la aplicacion 
CC-Monitor que me indica que la version es 15.2

No voy a actualizar todos los moviles. Solo 2 de ellos tendran la version 15.2 
y otros 2 tendran la 14. El resto, para pruebas.

Esto es una ventaja de Siemens sobre Nokia: permiten que el usuario actualice 
desde casa su movil usando un cable estandar, que viene incluido cuando compras
el telefono.

El programa que sirve para actualizar la memoria flash resulta ser un 
ejecutable de 25 Mg. Espero buscar los mensajes que muestran las aplicaciones 
del movil, para hacer mi propia version, pero no encuentro las cadenas de texto.
Es posible que el actualizador este comprimido o cifrado.

Activo el puerto infrarrojos del movil y del ordenador, y veo que pueden 
comunicarse. El programa irftp incluido en Windows permite transferir en ambas 
direcciones, asi que meto unos cuantos de los juegos que he bajado de la red. 
A mi siempre me ha gustado mas la programacion, pero una partida de vez en 
cuando no esta mal.

Mirando en los foros descubro que es posible emular juegos de la N-Gage de 
Nokia, pues ambos tienen el mismo sistema operativo Symbian.
Para eso hay que instalar un parche que tambien tengo. Lo que no se es como se 
aplica el parche, que es del tipo
replace:0032040504350410:00B240A205402A0

Esto me resulta de lo mas extrano. En los otros modelos de Siemens los parches 
son simpre un cambio en una direccion fija de memoria, del tipo
0xC12346: 045A 032A
pero al parecer en el SX1 los parches se limitan a buscar una cadena, y 
reemplazarla por otra.
Deduzco que esto es asi porque hay varias versiones de firmware, y la misma 
cadena puede estar en distintas posiciones de memoria dependiendo de la version.
?Pero que pasa si mi version no tiene esa secuencia de caracteres?
Ademas, esa cadena no aparece en el fichero FW15.2[CS].exe por lo que no puedo 
aplicar el parche. Me quedo sin poder jugar a la N-Gage .

Mas descubrimientos: existen unidades de disco:
Z: es donde esta el sistema operativo. La unica manera de escribirlo es
   actualizando el firmware.
E: es la tarjeta MMC - MultiMedia Card. Aqui es donde se suelen instalar los
   programas, canciones, videos, ...
D: es un disco RAM. Los datos se pierden cuando se resetea el movil. Se usa
   como almacenamiento temporal.
C: es otro disco en el que se pueden guardar programas. En particular los SMS
   se guardan aqui, y tambien los programas transferidos por infrarrojos,
   aunque luego se pueden instalar en E: o en C:
A: es de solo lectura. Aqui estan los programas que la operadora de red le pide
   a Siemens o a Symbian. Hay algunos juegos, un reproductor mp3, la radio, y
   el RealPlayer para ver videos. En la version 14 fabricada a medida para la
   empresa O2, tambien hay un navegador hecho a medida.

La manera mas comoda de instalar programas es usar un escritor de tarjetas MMC 
y luego meter la tarjeta en el movil.
Pero como yo no tengo un lector (ya se que solo cuestan 10 euros) los tengo que
transferir por infrarrojos. El programa para usar el puerto USB no consigo que 
me funcione.

COn esto se me han pasado algunas horas. Momento de cine y unas copichuelas.

04/09 *********** Domingo *********** 
Dia de descanso. Hoy no enchufo el ordenador. Pero he notado que la bateria 
dura menos de 48 horas, por lo que me tendre que acostumbrar a dejarlo cargando
todas las noches.


05/09 *********** Lunes *********** 
Entre unas cosas y otras no he podido surfear, pero me ha dado tiempo para ver 
la respuesta en el foro CS. Basicamente solo hay parches para cambiar los 
iconos, musicas, tipos de letras, pantalla de inicializacion, y otros que hacen
que alguna aplicacion lea los ficheros de E: en vez de Z: , para poder meter 
mis propios iconos.
Pero no hay parches funcionales. Quizas es muy complicado. Pero de verdad me 
gustaria cambiar algunas cosas. Por ejemplo, para instalar una aplicacion hay 
que aceptar algunas verificaciones, en total 5 mensajes !
Si fuera posible eliminar algunas de estas preguntas, la instalacion seria mas 
comoda.

Con la aplicacion FExplorer he podido ver que cada aplicacion tiene un 
identificador unico, para que no se instale 2 veces. No solo eso, sino que la 
misma aplicacion no puede ejecutarse a la vez 2 veces, lo cual tiene bastante 
sentido para un juego, pero no para el Notepad.


06/09 *********** Martes *********** 
Hoy me he bajado el OggPlay para escuchar musica. Tiene algunas cosas mejores 
que el reproductor mp3 que viene incluido, pero el formato de las canciones es 
diferente. Tendre que convertirlas a formato OGG. Para eso uso el programa 
"ACE-HIGH Converter".
Malas noticias: si escucho canciones durante mas de tres horas, la bateria se 
agota. No dura casi nada, en parte debido a que no hay posibilidad de cambiar 
la intensidad de la iluminacion. ?Para que necesito que ilumine durante el dia?
Esto es un fallo grave de diseno.

Mas investigaciones: las aplicaciones de la unidad Z: ocupan una media de 20 Kb,
y tambien hay un monton de librerias en Z:\System\Libs . En total hay unos 
1.500 ficheros.

Transfiero alguno de ellos al PC, y lo unico que veo en claro son algunas 
cadenas de caracteres, en formato Unicode, esto es, que cada car'cter ocupa 2 
bytes.
Por ejemplo, el fichero z:\system\libs\MenuEng.dll contiene la cadena
Z:\system\data\op_folder.mbm
ocupando 28*2 bytes

Un parche tipico es cambiar la primera Z por E para que el fichero se lea desde
E: , donde es posible alterarlo.
Pero sigo sin saber como meter un parche, ni tampoco se que es un fichero de 
tipo mbm .


07/09 *********** Miercoles *********** 
Desde la web de oslik he encontrado muchas utilidades:
-RSCTool, para cambiar archivos de recursos, de extension .rsc
-MBMTool, para archivos de imagenes MBM: Multi-Bit-Map
-UnMakeSIS, para ver los ficheros dentro de un archivo SIS, que es un 
 instalador de aplicaciones
-SISTool, para lo mismo
-AIFTool, para leer archivos AIF: Application Information File , con los iconos
 y nombre del programa
-WSFFXBI, para extraer un XBI desde un WinSwup (tal como FW15.2[CS].exe ) y
 viceversa
-Xbi_Extract, para romper un XBI en pedazos, uno para cada unidad A: , Z: ,
 bootcore, ...
-WSMP para meter parches en un XBI

Ademas, desde la web de CS he encontrado manuales para la mayoria de estos 
programas.
Brevemente:
-el WinSwup se convierte en XBI usando WSFFXBI
-el XBI se parchea con WSMP
-el XBI se convierte en WinSwup con WSFFXBI
-el WinSwup se ejecuta, que instala la nueva version.

El fichero XBI extraido de esa manera contiene una copia de todos los ficheros 
en Z:

Manos a la obra. Elijo uno de los parches para leer menu_folders.mbm desde E: ,
sigo los pasos anteriores, y cuando inicio el movil, se resetea. ?Que he hecho 
mal? Obviamente, me he olvidado de copiar menu_folders.mbm en E: 
Menos mal que tengo otro movil. Cambio la tarjeta MMC, copio el archivo usando 
FExplorer, y ahora funciona en el movil parcheado !
Los iconos son los mismos que antes, pero con el MBMTool descomprimo 
menu_folders.mbm y cambio uno de los dibujos, lo transfiero al movil, lo copio 
en E: , y tras resetear el movil, el nuevo icono aparece.
Bueno, todo un acontecimiento.


08/09 *********** Jueves *********** 
Hoy ha surgido el tipico marron del jueves, asi que no me quedan tiempo ni 
ganas de enredar con el movil. Queria hacer algo porque el fin de semana tengo 
otro asunto planeado, pero no va a poder ser.


09/09 *********** Viernes *********** 
Uso el programa FileMan para transferir todos los archivos de Z: hasta E: y 
despues los meto en el PC. Hago un programa que busca una cadena de caracteres 
dentro de cada uno de los ficheros, para ver cuales archivos son usados por 
otros programas, y hacer una especie de arbol relacional.
Los archivos avkon.mbm, EidPic.mbm y Muiu.mbm se usan muy frecuentemente por 
otras aplicaciones. En particular avkon.mbm contiene 250 iconos usados a lo 
largo de todo el sistema operativo. No hay parches para usarlo desde E: , pero 
hay parches para cambiarlo en Z: .
El motivo de no meterlo en E: es que la unidad E: esta en la MMC, y es muy 
lenta de acceder. La unidad Z: esta siempre en memoria, asi que los iconos se 
pueden acceder sin demoras.
Pero yo no pretendo cambiar los dibujos. Hay muchos artistas por ahi, y yo lo 
maximo que se hacer es la letra O, ayudado por un canuto.
Bueno, no me da tiempo para mas antes de que salgamos de viaje.

10/09 *********** Sabado *********** 
Londres esta cada dia mas caro. 35 libras por chicken-tikka-massala y 
KingFisher para dos !

11/09 *********** Domingo *********** 
Me encanta el flea market. Sobre todo las tiendas de discos de alrededor.

12/09 *********** Lunes *********** 
Como no he dormido mucho el fin de semana, estoy cansado y hoy tampoco toco el 
ordenador.

13/09 *********** Martes *********** 
He abierto la aplicacion Notepad.app con un editor hexadecimal y he averiguado 
que los primeros bytes es una cabecera disenada siguiendo un estandar:
-los primeros 4 bytes son 79000010 que escritos en little-indian significan
 0x10000079. Todas las aplicaciones de tipo *.app empiezan por estos bytes.
-los segundos 4 bytes son 0x100039CE , y tambien sucede con muchas aplicaciones
 *.app . Este numero magico se llama KAppUidValue16 , y significa que la
 aplicacion es Unicode, es decir, que puede contener mensajes con caracteres no
 ASCII.
-los terceros 4 bytes son 0x10005907. Al ejecutar la aplicacion y mirar con
 TaskSpy, este es el numero identificador. Asi que cada programa tiene un
 numero unico.
-el cuarto grupo vale 0x3EB18517, y es otro identificador, aunque no
 necesariamente unico.
-cada uno de estos numeros se llama UID: Unique IDentifier
-el siguiente grupo vale 0x506D53D5 e indica el punto de inicio del programa.
 Para aplicaciones en Z: esta es exactamente la direccion en la que estan
 ubicados.

Lo explicare mejor: la memoria en Symbian es un bloque de 16 Mb que se carga a
partir de la direccion 0x50000000. Cada fichero, por el hecho de estar en este 
gran bloque, va a parar a una direccion de memoria. Pues bien, esta direccion 
tambien esta escrita en el propio fichero.

Los programas que residen en A: , C: o E: son cargados dinamicamente, por lo 
que su direccion no es siempre la misma. Pero Symbian tiene un mecanismo de 
memoria paginada que hace que todos los programas aparezcan como cargados en 
la direccion 0x00400000, aunque obviamente el gestor de tareas se encarga de 
alternar entre uno y otro, lo que se conoce como actualizacion de entorno. 
Esto existe en practicamente todos los sistemas operativos multitarea de disco.

-El siguiente dato es 0x506D53D4 (uno menos que el anterior) e indica la
 direccion donde empieza el codigo.
-Luego viene 0x00000000 que es la direccion de los datos. Al ser 0 quiere
 decir que no hay datos pre-inicializados, y la propia aplicacion se encargara
 de solicitar la memoria necesaria cuando llegue el momento.
-Sigue el dato 0x00000AE0 que indica el tamano del codigo. Este programa ocupa
 0x0AE0 = 2784 bytes.
-Despues va 0x00000ADC que es el tamano total. Es el dato anterior, menos 4.
-A continuacion 0x00000000 que es el tamano de los datos.
-Otra vez 0x00000000 para indicar el tamano del BSS, es decir, la pila.
-El siguiente es 0x00100000 = tamano maximo de la pila.
-Sigue 0x00001000 = tamano minimo de la pila.
-Despues, 0x00002000 = tamano del stack para las rutinas.
-y 0x50F17610 indica las referencias a DLL. Esto dice cuales rutinas son usadas
 desde otras librerias.
-El dato 0x00000001 dice que solo hay 1 funcion exportada.
-0x50F1760C indica la lista de funciones exportadas, precisamente la de
 inicializacion del programa, correspondiente a la funcion main.

Esto me va a servir para saber cuales programas llaman a las librerias, y por 
tanto las funciones exportadas. Lo que no se es el significado de cada rutina.


14/09 *********** Miercoles *********** 
He estado paseandome por la web de Symbian y he bajado el SDK que sirve para 
hacer programas.
El lenguaje es C/C++ pero un poco anticuado. Cuando los desarrolladores de 
Psion (predecesor de Symbian) inventaron su sistema operativo, C++ todavia no 
tenia un mecanismo de excepciones maduro.
Esto hace que las aplicaciones Symbian tengan que encargarse ellas mismas de 
liberar la memoria que soliciten. A la porra toda la funcionalidad del 
recolector de basura, auto-destruccion, y ademas complica el polimorfismo.
Esto parece ser una grave inconveniencia para hacer programas de usuario, segun 
he estado leyendo.

Por lo menos he visto que existen 2 sitios web dedicados a la programacion en 
Symbian:
www.newlc.com
allaboutsymbian.com , que frecuentemente esta sobrecargado.

Desde la web de Siemens me he bajado el SDK especifico para el SX1. Ocupa 200 
Mg comprimido, y 600 Mg instalado completamente.
Lo he instalado y veo que incluye un emulador. Pero apenas cubre el 30% de la 
funcionalidad real del telefono.
Para empezar, la aplicacion principal es el menu, desde el que se pueden 
iniciar otras aplicaciones.
En el movil real esto no es asi, sino que la aplicacion es llamada Phone.app , 
con posibilidad de iniciar llamadas, acceso rapido a aplicaciones (manteniendo 
pulsada una tecla durante 2 segundos), gestion del manos libres, ...
Por ejemplo: cuando el movil no hace nada, pasa a la aplicacion Phone.app . Si 
se pulsa el joystick hacia abajo, se inicia la aplicacion de la agenda. Esto 
no se puede hacer desde el emulador, y precisamente yo estaba interesado en 
esto.

Si el emulador no es perfecto, la documentacion es todavia peor. Es cierto que 
explica muchas cosas, pero como un manual de referencia; no cuenta en detalle 
como usar esas librerias.
Al menos hay muchos ejemplos que tendre que investigar. Necesito el compilador 
Microsoft VC 6.0  porque no funciona con versiones superiores ! Lo unico que 
usa es el  nmake  , pues el compilador es el GCC, incluido en el SDK.

Intento compilar el ejemplo HelloWorld, pero se queja de que no tengo instalado
el Perl. Manana me lo bajare.


15/09 *********** Jueves *********** 
Por fin tengo todas las herramientas, incluido el Cygwin para usar un automake 
y un shell decente.
Me cuesta un poco compilar la primera aplicacion, pero al final consigo 
HelloWorld.app
El metodo es el siguiente:
-poner bien la variable EPOCROOT, en mi caso \Symbian\6.1\Siemens\SX1\bin\
-pasar al directorio  ....\group\
-bldmake bldfiles    para que construya el proyecto
-abld makefile   para defini cuales archivos son necesarios: fuentes, cabeceras,
 dibujos, ioconos, sonidos, ...
-si se quiere hacer la aplicacion para el emulador: abld build wins urel
-si se hace para el movil real: abld build armi urel

Parece que empiezo bien.  La aplicacion HelloWorld.app funciona en el emulador.
Meto en el movil la version compilada para armi , pero se resiste a arrancar.

Tras leer mucha documentacion, parece ser que no vale con copiar la aplicacion 
en el movil; es necesario instalarla adecuadamente con HelloWorld.sis
Para esto hay que hacer
-makesis HelloWorld.pkg

Ahora se deja instalar adecuadamente, pero cuando la inicio, da un error y sale.

Tras muchas pruebas y perder el tiempo, lo intento con otra aplicacion simple 
llamada Language y esta funciona !
No es una maravilla de aplicacion, pero al menos tengo algo que funciona.

Lo que estaba haciendo era correcto. Simplemente que la aplicacion HelloWorld 
parece no funcionar en el movil.


16/09 *********** Viernes *********** 
La conexion a Internet del trabajo esta que echa humo. Hace 2 dias me descargue
el SDK, ayer el Perl y el Cygwin. Hoy me he bajado todos los ejemplos de 
programacion que he encontrado. Un monton de documentacion desde la web de 
Nokia, y algunos juegos que he encontrado por el camino.
A ver si tengo tiempo para organizarlo todo. Leerlo me llevara mucho mas 
tiempo, por supuesto.

Me sorprende que Nokia parece darle mucho mas apoyo al sistema operativo 
symbian que la propia compania Symbian.
Sus foros estan llenos de preguntas sobre programacion. Lamentablemene no hay 
muchas respuestas.
La mayoria de los temas parecen centrarse en "como hacer una llamada automatica" y "como hacer un programa que mande SMS".
Lamentablemente en las webs de CS, oslik, y www.siemens-mobile.org (en 
adelante, SMO) los foros de programacion estan bastante vacios.

Pero por ahora estoy bastante contento. Han pasado 3 semanas desde que tengo 
los moviles, y ya me hago una idea de lo que es capaz de hacer el SX1. Esto se 
merece una mini-celebracion. Comida mongola para dos, que a mi chica tambien le
apetece ir a un sitio exotico.

17/09 *********** Sabado *********** 
Como ya he comentado, al pulsar el joystick hacia abajo se inicia la aplicacion
de contactos, llamada Phonebook.
Tiene un UID con valor 0x101F4CCE
Lo que pretendo hacer es cambiarlo para que inicie otra aplicacion distinta.

Al pulsar el joystick hacia arriba se inicia la aplicacion de ultimas llamadas 
recibidas y enviadas, que se llama Logs y tiene UID=0x101F4CD5

Supongo que la aplicacion que gestiona el joystick usa ambos valores en rutinas
similares; simplemente inicia Phonebook.app o Logs.app

Para buscar esos bytes, recordar que hay que cambiar el formato a little-indian,
por lo que 0x101F4CCE hay que buscarlo como CE.4C.1F.10

Mirando en el archivo XBI generado a partir del FW15.2[CS].exe lo encuentro en 
11 sitios.
Obviamente uno de ellos corresponde al UID del propio fichero Phonebook.app 
pero este no lo puedo cambiar.
Otros sitios son en Phonebook.aif, que es el fichero con la configuracion del 
propio Phonebook.
Otro de los sitios es en la aplicacion Phone.app que si recuerdas es la que 
esta ejecutandose cuando estas en el menu principal, precisamente cuando puedes
pulsar el joystick para que arranque otras aplicaciones.
No solo eso, sino que encuentro la cadena de bytes:
CE4C1F10 D54C1F10
es decir, los UIDs de las dos aplicaciones que se pueden ejecutar con el 
joystick.
Modifico estos datos en el XBI para que apunten a la calculadora 
(UID=0x10005902) usando los bytes
02590010 en vez de CE4C1F10
y tras instalar el firmware modificado observo con regocijo que ahora abre la 
calculadora !

Primer parche funcional en mi carrera del SX1.

Lo meto en un fichero de texto, le pongo unos cuantos comentarios, y lo preparo
para publicarlo en CS. A ver que les parece.

Este parche no tiene nada de programacion, pero los siguientes seguro que si.

Para intentar entender como funcionan los programas, necesito desensamblarlos. 
Para el modelo S45 usaba el IDA dissasembler, que es un gran programa, aunque 
un poco caro. Pero lo he usado tanto que me parece justo pagar por el.
Ademas incluye soporte para ARM. Cargo el IDA, le digo que destripe el 
Notepad.app, y lo identifica como un fichero EPOC, es decir, de la antigua 
version Symbian. Pero luego se hace un lio con las cabeceras. Lo mejor es 
decirle que es un fichero binario puro, por supuesto para el procesador ARM, 
en concreto ARM710a .

Entonces hay que decirle cual es la direccion en la que tiene que cargarlo.
La cabecera tiene el dato 0x506D53D4 que dice que el codigo empieza 
precisamente ahi.
Pero como he cargado el fichero entero, tengo que excluir el tamano de la 
cabecera, es decir, restarle 0x64 bytes para obtener 0x506D5370.
Esa es la direccion de inicio, y ademas genero una seccion de ROM con 
exactamente la misma direccion.

Cuando lo carga, no desensambla nada. Todavia me faltan un par de pasos.

El procesador ARM tiene 2 modos de funcionamiento.
Uno llamado ARMI, en el que las instrucciones de codigo ocupan 4 bytes. Es mas 
rapido, mas potente, pero consume mas bateria y ocupa mas espacio.
El otro modo se llama THUMB, y las instrucciones ocupan 2 bytes. El codigo es 
mas compacto, pero mas limitado. Algunas operaciones solo se pueden ejecutar 
en ARMI. A cambio, consume menos.
En particular, el kernel y los drivers estan compilados en ARMI, y los 
programas de usuario en THUMB.

Como IDA esta configurado por defecto para desensamblar en modo ARMI, no 
empieza el desensamblado automatico.
El programa Notepad.app esta compilado en THUMB. Para que IDA lo pueda 
desensamblar hay que que cambiar el registro T con valor 1, usando la tecla 
Alt-G
Ahora ya lo puedo desensamblar. Selecciono todo el trozo de programa desde la 
direccion 0x506D53D4 y le digo que lo analize.
Al cabo de un par de minutos me ha generado un listado de 150 rutinas, de unas 
2000 lineas en total.
Pero no se lo que significan las rutinas. Espero encontrar un listado de ellas 
en algun sitio del SDK. Pero eso sera otro dia.

Ahora, al cine y a darnos ir garbeo.

18/09 *********** Domingo ***********
Tal como sospechaba, las cabeceras del SDK (*.h) contienen los nombres de 
muchas de las funciones exportadas.
Por ejemplo, la documentacion dice que hay una funcion llamada FileExists() 
que esta declarada en coeutils.h e implementada en cone.lib
Efectivamente, coeutils.h contiene la linea

public:
   IMPORT_C static TBool FileExists(const TDesC& aFileName);

Y el fichero cone.lib contiene la palabra FileExists , mas concretamente 
"FileExists__9ConeUtilsRC7TDesC16".
Esto es la notacion que usan las librerias en Windows, y significa que es una 
funcion que:
-toma como argumento un objeto de tipo TDesC16
-devuelve un objeto de tipo 9 , es decir, un TInt (o un TBool, que es lo mismo)

Para saber cual es el numero dentro de esta libreria, uso el programa ar 
(Archive) :
ar -tv cone.lib
que resulta tener 319 funciones. El fichero ds00063.o contiene la palabra 
"FileExists", asi que ya se que la funcion 63 de ConeUtils es FileExists.
Esta funcion esta implementada en la libreria Cone.dll del movil, pero no se 
cual es el punto de entrada a la rutina.

Asi que cargo el fichero ds00063.o en IDA, que lo identifica como ARM COFF 
(little endian)
Pero el desensamblado no me da ninguna pista. Lo unico que contiene es una 
referencia al numero 0x3F = 63 , pero esto ya lo sabia yo.

Asi que cojo el programa Language que consegui compilar el otro dia, y hago 
que use la funcion FileExists .
No me molesto en hacerlo funcionar. Lo unico que quiero es saber como hace 
para referenciar a la funcion 0x3F.
Y en realidad es bastante sencillo:
el compilador crea una funcion sub_10009A88 que servira como punto unico de 
entrada:
sub_10009A88
 LDR     R3, off_10009A90 
 LDR     R3, [R3]
 BX      R3

el registro R3 apunta a una direccion de memoria:
off_10009A90     DCD 0x1000BD60

en esta direccion se invoca a la funcion de la libreria externa:
; Imports from CONE.DLL
1000BD60         IMPORT FileExists__9ConeUtilsRC7TDesC16

Este ultimo dato sera rellenado por el ejecutor de tareas en el movil: carga 
la aplicacion en memoria, rellena la tabla de referencias, y salta a la 
direccion de inicio de la aplicacion.
Esto es algo tipico de los sistema operativos que usan librerias dinamicas.

Lo que no me gusta tanto es que hay una referencia a una referencia a una 
referencia. Asi va a ser dificil seguir el flujo de los programas.
Y tampoco me gusta que las rutinas tengan nombres como 
FileExists__9ConeUtilsRC7TDesC16. Preferiria algo mas legible.

Empiezo a darle vueltas a la cabeza para hacer un programa que saque los 
nombres en claro, a partir de los nombres incluidos en las librerias y los 
ficheros de cabecera. Primero necesito meditarlo, y luego programarlo.

19/09 *********** Lunes ***********
He publicado el parche en CS, y parece que ha tenido cierta aceptacion. No 
porque sea terriblemente util, sino porque 
es de los primeros parches funcionales. Recibo muchos animos de la comunidad.

Por otro lado, busco algun programa que me ayude a sacar los nombres de las 
librerias.
El truco esta en usar el programa dumpbin.exe incluido con el VisualC++ :

dumpbin /ALL cone.lib
..........
  Version      : 0
  Machine      : 14C (i386)
  TimeDateStamp: 3FAA5B88 Thu Nov 06 14:32:40 2003
  SizeOfData   : 00000032
  DLL name     : CONE.DLL
  Symbol name  : ?FileExists@ConeUtils@@SAHABVTDesC16@@@Z
  (public: static int __cdecl ConeUtils::FileExists(class TDesC16 const &))
  Type         : code
  Name type    : ordinal
  Ordinal      : 76
................

Unas cuantas de lineas de Perl , y ya tengo sacadas todas las definiciones de 
las librerias.

Vamos a ver si me sirve de algo:
Hay un programa llamado torch que lo unico que hace es mantener encendida la 
constantemente pantalla del movil, por si necesitas una linterna. Bastante 
inutil, pero es simple.

Tengo el torch.sis que vale para instalarlo.
Con el programa SISTool veo que consiste en 4 archivos:
-Torch.app, con la aplicacion
-Torch.rsc, con los recursos, es decir, los textos de los dialogos y los menus
-Torch_caption.rsc con el nombre de la aplicacion
-Torch.aif con el icono de la aplicacion y el UID

El que me interesa es el primero. Lo extraigo, y lo paso por el IDA.

Veo que usa:
10000FCC IMPORT Start__9CPeriodicG27TTimeIntervalMicroSeconds32T1G9TCallBack

la cual es referenciada en:
off_100003EC    DCD Start__9CPeriodicG27TTimeIntervalMicroSeconds32T1G9TCallBack

que es llamada desde:
sub_100003E0
 PUSH    {R6}
 LDR     R6, =Start__9CPeriodicG27TTimeIntervalMicroSeconds32T1G9TCallBack
 LDR     R6, [R6]
 MOV     R12, R6
 POP     {R6}
 BX      R12

invocada desde:
.text:100001E4  LDR     R2, =0x989680
.text:100001E6  LDR     R0, =(loc_10000298+1)
.text:100001E8  STR     R0, [SP,#0x14+arg_0]
.text:100001EA  STR     R4, [SP,#0x14+arg_4]
.text:100001EC  LDR     R0, [R4,#0x30]
.text:100001EE  ADD     R1, R2, #0
.text:100001F0  LDR     R3, [SP,#0x14+arg_0]
.text:100001F2  LDR     R4, [SP,#0x14+arg_4]
.text:100001F4  STR     R4, [SP,#0x14+var_14]
.text:100001F6  BL      sub_100003E0
.text:100001FA  ADD     SP, SP, #0x1C


Vamos a ver si lo entiendo (desde abajo hacia arriba):
100001F6  llama a    sub_100003E0
en 0x100001F4 mete en la pila el valor de R4
que en 0x100001F2 lo ha sacado desde la pila
Tambien R3 lo ha sacado en 100001F0 desde la pila 
En 0x100001EE ha hecho R1=R2+0
Me salto las otras instrucciones hasta 0x100001E4 , en donde hace
R2=0x989680
este valor es 10.000.000 en decimal y se le pasara como segundo argumento a la 
rutina sub_100003E0 , o sea,
void Start(TTimeIntervalMicroSeconds32 aDelay,TTimeIntervalMicroSeconds32 
anInterval,TCallBack aCallBack);

Obviamente quiere decir que cada 10 segundos llamara a una funcion que 
re-encendera la pantalla.
Pero mi pantalla no se apaga automaticamente a no ser que no pulse ninguna 
tecla durante 20 segundos. Podria cambiar el valor 10.000.000 por 20.000.000 , 
y me ahorro algo de proceso.

Vale, no es el cambio que va a arreglar el mundo, pero yo solo pretendo 
aprender.

Ahora es cuando tengo que admitir que he hecho trampa. El programa Torch es de 
codigo abierto, y tengo el codigo fuente original, por lo que podria haberlo 
cambiado, recompilar, y a correr.

20/09 *********** Martes ***********
Los programas que puedo instalar en el movil siempre tienen una tabla de 
funciones importadas, para que el iniciador de tareas los pueda unir con las 
librerias dinamicas. Esto hace sencillo averiguar los nombres de las funciones 
usadas, con lo que es facil hacerse una idea de lo que hacen los programas, a 
no ser que usen trucos complicados, o el programa sea demasiado grande para 
analizarlo.

Pero los programas que vienen incluidos en el movil no son dinamicos. Ellos 
_saben_ exactamente donde estan las librerias, pues forman parte del mismo 
sistema.
Por poner un simil, imagina que tienes que usar un teclado de un ordenador en 
otro idioma. Las teclas pueden estar en una posicion distinta, por lo que tu 
tienes que mirar el teclado constantemente.
Pero los nativos del pais ya saben donde estan las teclas, y pueden escribir 
mas rapido.
Esta ventaja tambien existe en los programas nativos: se cargan mas rapidos 
porque no es necesario resolver las dependencias de enlace; ya fueron resueltas
en tiempo de compilacion.

A cambio dificultan la tarea de aquellos que, como yo, pretenden modificar los 
programas nativos.
Primero tengo que averiguar cuales son las rutinas llamadas, suponiendo que 
esten documentadas.

Empiezo por atacar al Notepad.app . No es una gran aplicacion, pero voy a ver 
que saco.

Lo primero que encuentro es que hay un trozo con las instrucciones:
BX R1
NOP
NOP
BX R2
NOP
NOP
BX R3
NOP
NOP
....
BX R13
NOP
NOP

(la instruccion BX indica "saltar a")

Estas son rutinas de acceso indirecto o indexado.
Supongamos que tengo una rutina que quiero que haga
if(x=100) salta a rut100;
if(x=101) salta a rut101;
if(x=102) salta a rut102;
if(x=103) salta a rut103;

esto es mas eficiente si hago
lista_ruts={rut100, rut101, rut102, rut103};
lista_vals={100, 101, 102, 103};
for(i=0;i<sizeof(lista_vals);i++)
 if(x==lista_vals[i])
  {
  R1=lista_ruts[i];
  salta a R1;
  }

En otras palabras: este troz ode codigo actua simplemente como un trampolin 
para saltar a otra rutina.
Aunque la pregunta es clara: si tengo
BX R1
?para que necesito  BX R2 ?
Bueno, la respuesta es que a veces necesitas mandar un parametro, y el primer 
parametro que admite una rutina siempre es R1.
Ya, ya, entonces te preguntas si de verdad hay funciones con 14 parametros.
La respuesta es no. Pero al parecer el compilador siempre incluye todas las 
intrucciones
BX R_??

Mas cosas: casi todas las rutinas empiezan guardando los registros que van a 
corromper.
En ARM existe una instruccion que puede meter varios registros en la pila, por 
ejemplo
PUSH {R4-R6,LR}
metera los registros R4, R5, R6 y LR
obviamente al final de la rutina se hace
POP {R4-R6}
y despues
POP R1
BX  R1
que es equivalente a
RET
Esto me ayuda a saber donde termina una rutina y empieza la otra.

Otra curiosidad mas: existe una intruccion para cargar valores sencillos en un 
registro:
MOV R0, #0x1C
pero solo se pueden cargar valores de 8 bits.
Para cargar un valor mas grande (de 32 bits) hay que hacerlo con una referencia:
LDR R4, val(dato_grande)
.....
dato_grande DCD 0x12345678

Notar que se usa el comando LDR en vez de MOV . Hace lo mismo, pero sirve para 
cuando usas referencias.

A menudo se usa un truco consistente en multiplicar el valor por otro.
Por ejemplo, no se puede hacer
MOV R1, #0x124

pero se puede hacer
MOV R1, #0x49
LSL R1, R1, #2

que desplaza R1 hacia la izquierda 2 veces, es decir, lo multiplica por 4, y 
#0x49*4 = #0x124

Al principio me cuesta un poco entender el ensamblador del ARM, pero en 
realidad es mas sencillo de lo que parece.
A decir verdad, no he aprendido mucho del funcionamiento real del Notepad, 
pero creo que ha sido util.

21/09 *********** Miercoles ***********
Me he bajado de la red unos manuales de ARM, porque hay algunas instrucciones 
que no consigo entender: MCR, MSR, registro CFSR, P15, ...
Por lo que averiguo, solo se usan para tiempo real y para gestionar la cache de
memoria y otras cosas mas complicadas.
Me las he encontrado en el Notepad.app porque en realidad estaba desensamblando
una parte de datos, no de codigo, con lo que IDA se ha liado y me ha confundido
tambien a mi.

En el foro de CS he visto que alguien queria eliminar un mensaje que aparece 
cuando cambias la tarjeta MMC sin antes notificarselo al movil. Lo explicare 
mejor: el SX1 puede leer tarjetas de memoria. Las que yo tengo son de 128 Mg, 
con lo cual caben muchos programas y canciones.
La tarjeta esta ubicada en un lateral, y no es necesario apagar el movil para 
cambiarla.
Cuando quieres meter otra tarjeta, hay que ir a un menu, que se encarga de 
cerrar los archivos abiertos, y finaliza las aplicaciones que se estan 
ejecutando desde la memoria MMC.
Pero tambien es posible sacar la tarjeta sin usar el menu. Eso si, te arriesgas
a perder datos.
Cuando lo haces asi, el movil muestra un mensaje advirtiendo que no es 
recomendable sacar la tarjeta de esta manera violenta.
Este usuario del foro queria que no saliera este mensaje.

Lo primero que he hecho es buscar este mensaje "Puede perder datos si extrae 
su tarjeta MMC" por todos los ficheros. No lo he encontrado, lo cual me 
sorprende bastante. Quizas esta comprimido.

Lo siguiente que he hecho es averiguar cual es la aplicacion que muestra el 
mensaje.
Hago un programa que muestre un mensaje simple, y veo que el compilador incluye
una referencia a CAknGlobalNote::ShowNoteL

Por el nombre, y un poco de suerte, descubro que esta funcion esta definida en 
AknNotify.dll 

veo que tras un par de comparaciones, llama a una funcion sub_503EB9B4 que a 
su vez llama a
RNotifier::StartNotifierAndGetResponse(TRequestStatus &, TUid, TDesC8 const &, 
TDes8 &)

Asi que decido parchear esta rutina para que no haga nada.
Modifico el firmware, lo meto en el movil, y ahora no muestra ese mensaje. Ni 
ese, ni ningun otro !
Creo que la rutina esta es llamada desde muchos otros sitios.

Deshago el cambio, y ahora parcheo sub_503EB9B4 . Lo mismo. No sale ningun 
mensaje.

Asi que miro cuales rutinas llaman a 
CAknGlobalNote::ShowNoteL
y descubro que hay un total de 50 aplicaciones que importan una referencia a 
esta rutina.

Tengo que encontrar cual es la aplicacion exacta. Si hubiera encontrado el 
texto del mensaje "Puede perder datos si extrae su tarjeta MMC" entonces seria 
mas sencillo.
La solucion en este caso es tediosa: anulo 25 de las llamadas. Si sigue 
apareciendo el mensaje, es que esta en una de las llamadas no anuladas. 
Repitiendo este proceso de nuevo, me quedan 13 llamadas. Luego 7, despues 4, 
mas tarde 2, y por fin averiguo que la aplicacion es SysApp.app
La desensamblo, y descubro que llama a CAknGlobalNote::ShowNoteL desde 20 
sitios distintos. Recordar que solo hay una referencia, pero puede ser invocada
desde distintas rutinas dentro de la misma aplicacion.
Como no me apetece buscarlo otra vez, anulo la llamada en esta aplicacion, aun 
sabiendo que no solo se elimina ese mensaje, sino otros 19 tambien.

El proceso de meter el firmware en el movil lleva unos 10 minutos, sin contar 
el tiempo que necesito para analizar las rutinas. Se me hacen las 2 de la 
manana cuando tengo algo parecido a un parche.
Lo preparo para publicarlo en CS, a ver que opinan. Incluyo una advertencia de 
que es posible que elimine otros mensajes.

22/09 *********** Jueves ***********
No he podido publicar el parche porque la web no funcionaba. Mejor, asi puedo 
depurarlo mas.
Pero no hoy, que tengo que ir de compras, y a mi me cuesta un monton decidirme 
por una camisa.

23/09 *********** Viernes ***********
Como todavia no he podido mejorar el parche, no lo publico. Asi tengo el fin de
semana entero para mejorarlo.
Lo que veo es que necesito un sistema para seguir en vivo cuales son las 
rutinas que se llaman. Hice algo parecido para el S45, pero para el Symbian 
necesito aprender mucho todavia.

Lo que he averiguado es que la memoria flash del firmware se mapea en la 
direccion 0x50000000 ; por eso todos los programas incluidos de serie se 
cargan a partir de ahi.
Pero no se como leer datos de esa direccion. Intento un programa con:
TChar *p, c;
p=0x50000000;
c= *p ;

pero la aplicacion da un error y es terminada.

Aprendo que es posible hacer las mismas barbaridades que en C, en particular 
referenciar a memoria que no esta inicializada, reservar memoria con alloc y 
luego no liberarla, y usar char * como un puntero a cualquier cosa.

Tambien veo que hay 2 zonas de memoria: heap y stack.
El stack es para los parametros en las llamadas a funciones, y para guardar 
datos, por ejemplo con PUSH y sacarlos con POP.
En cambio el heap es memoria interna al programa, usada por los objetos 
inicializados. Se reserva con malloc.
La programacion en Symbian se hace en C++ orientado a objetos. Esto obliga a 
usar:
-New en lugar de alloc
-no se pueden usar variables globales estaticas
-no hay senales entre procesos. Pero hay semaforos globales
-Unicode. Brevemente, esto quiere decir que cada letra de un String ocupa
 2 bytes.
-se usa el stack para guardar objetos persistentes. Luego hay que eliminarlos
 con CleanupStack

Esto ultimo es uno de los conceptos mas raros que me he encontrado.
Supongamos que hay una funcion que puede fallar.
Antes de llamarla hay que meter en la pila los objetos que queremos que se 
borren automaticamente si la funcion llamada falla.
Pero si no falla, es mi obligacion limpiarlos. O sea, que tengo que saber 
cuantos objetos he metido, y esto en cada uno de los posibles flujos del 
programa.

En C++ moderno, esto es mucho mas simple: cuando un objeto deja de estar 
referenciado, el recolector de basura lo elimina, y todos tan contentos.

En fin, he visto que esto es uno de los mayores quebraderos de cabeza de los 
programadores que intentan hacer algo para telefonos Symbian, y a menudo la 
aplicacion funciona bien, pero falla cuando menos lo esperas. Y por supuesto, 
es casi imposible saber cual es el objeto que te has olvidado de destruir.

Por la parte buena, he encontrado que se puede reservar una zona de memoria, y 
no se libera aunque el programa termine. Luego se puede reiniciar el programa, 
y encadenarse de nuevo a la memoria anterior.
Esto se llama Chunk.
Eso me va a permitir crear una memoria para tracear el estado de los programas,
tanto mios como ajenos.

Pero esto es adelantar acontecimientos.

24/09 *********** Sabado ***********
Hoy he encontrado que es posible incluir codigo ensamblador dentro de un 
programa en C. Por supuesto que esto es logico, pero no es tan intuitivo como lo que yo estoy acostumbrado.
Un caso simple:
asm volatile ("MOV r6, r4" : : : "r6" );

Hace que el registro R6 reciba el valor del registro R4

El ensamblador del ARM es bastante sencillo. Hay 16 registros R0-R15 pero:
-R13 se usa como SP, es decir, el puntero a la pila.
-R14 se usa para guardar la direccion de retorno, antes de saltar a una
 subrutina.
-R15 es el registro PC, que indica donde estamos.
-R0 se suele usar como puntero al objeto. Esto lo explicare mas tarde.
-R1, R2 y R3 se usan como parametros a las funciones. Si la funcion recibe mas
 de 3 parametros, se usa la pila para los restantes.
-R9, R10 y R11 apenas se usan. Solo hay unas 20 rutinas que los modifican.
-los otros son usados como almacenamiento temporal, de proposito general.

Luego tiene unas cuantas peculiaridades, que algunos podrian considerarlos 
inconvenientes:
-Es posible asignar un valor a una variable, por supuesto, pero solo si cabe
 en 1 byte (thumb) o 3 bytes (ARM)
 Por ejemplo, en modo thumb es valido hacer
  mov r1, #0x1
 pero no
  mov r1, #0x12345678
 El truco es usar una referencia:
  mov r1, off_0x12345678
  off_0x101: DB 0x12345678
 Lo cuento porque esto fastidia a la hora de parchear programas.

Esto es mas evidente desde un programa en C :
int valor;
valor=0x12345678;
asm volatile ("MOV r6, %0" : : "r"(valor) : "r6" );

se convierte en
LDR R12, =0x12345678 ; equivalente a    int valor=*(off_0x12345678);
MOV R6, R12
...mas codigo...
off_0x12345678: DCD 0x12345678
que ocupa 2+2+4 bytes.

Otra instruccion importante es la que se usa para saltar a otra direccion de 
memoria.
Hay saltos cortos (no mas de 256*2 bytes) y saltos largos.
Los saltos cortos pueden incluir una condicion dependiente de la ultima 
operacion: si es igual, si es distinto, si es mayor, ...
Por ejemplo
 CMP R1, R0
 BEQ loc_xxx
que saltara a loc_xxx solo en el caso de que R1 sea igual que R0

Los saltos largos ocupan 4 bytes y pueden saltar a cualquier direccion, hasta 
16 Mg.
Dado que los programas de Symbian se ubican a partir de 0x50000000, esto obliga
a que el programa mas grande no puede saltar mas alla de 16 Mg. En otras 
palabras, todo el sistema operativo debe estar en menos de 16 Mb.

Por ultimo, las instrucciones PUSH y POP meten datos en la pila.
Sin embargo, en modo ARM se usa STMFD y LDMFD, por ejemplo
STMFD   SP!, {R4}
...
LDMFD   SP!, {R4}

desde un programa en C puedo hacer:
asm volatile ("STMFD   SP!, {R7}" : : : "r7" );
...
asm volatile ("LDMFD   SP!, {R7}" : : : "r7" );

Incluso es posible meter varios valores con una unica instruccion:
STMFD   SP!, {R4,R5}
...
LDMFD   SP!, {R4,R5}

Una cosa buena que descubro es que el codigo ensamblador generado por el 
compilador GCC esta optimizado, pero no demasiado. Es relativamente sencillo 
mapear un programa C con su equivalente en ensamblador, suponiendo que tienes 
acceso a ambos.
Como siempre, el codigo ensamblador tiene extension  .s

Tras un buen rato compilando programas y estudiando su resultado en 
ensamblador, me hago una idea de como funciona. Espero que esto me ayude a 
entender codigo ensamblador, y traducir (mas o menos) a su equivalente en C.

25/09 *********** Domingo ***********
Hoy voy a cambiar de enfoque. La verdad es que hasta ahora no tengo un 
objetivo definido; simplemente aprender tanto como pueda. Pero al usar el 
movil me doy cuenta de que hay ciertas cosas que no me gustan.
Una de ellas es que no es posible activar permanentemente el sistema de 
infrarrojos. Si no lo uso durante 1 minuto, se desactiva automaticamente.

Voy a ver si soy capaz de cambiarlo, dado que 1 minuto me parece poco.

El primer intento es buscar algun codigo que use el valor 60, pues sospecho 
que en algun sitio se define que 1 minuto son 60 segundos.
Lamentablemente el byte 0x3C (60, en decimal) aparece mas de 10.000 veces.

Voy con otro metodo: en un programa Symbian es posible llamar a una funcion 
para definir una tarea que se ejecute al cabo de un cierto tiempo. Este tiempo 
esta dado en millonesimas de segundo, aunque lo llama MicroSeconds.
Por tanto, 60 segundos se definiran como 60.000.000, que en hexadecimal se 
escriben como 0x03938700.
Convertido a little-indian (invertir los bytes de 2 en 2 desde el final), 
resulta 00879303
Busco esta cadena, y aparece 45 veces, en 24 ficheros.
De ellos, uno se llama IRLISTENSRV.dll y otro Iru.dll . Observar que incluyen 
la palabra "IR" en su nombre.

Desensamblo IRLISTENSRV.dll con IDA, y veo que hace
LDR     R0, =0x3938700
STR     R0, [R5,#0x6C]

y en otro sitio hace
LDR     R1, [R5,#0x6C]
BL      CIrListenActive::SetInactiveTimeout(TTimeIntervalMicroSeconds32)

Esta claro: primero hace que una variable global valga 60.000.000, y despues 
lee la variable, y pone un timeout. Cuando llegue el timeout, el sistema de 
infrarrojos se apagara. Supongo que cuando hay una transmision por el puerto, 
el timeout se pondra de nuevo a 60.000.000
Asi que para aumentar este valor, solo tengo que cambiar
LDR     R0, =0x3938700
por
LDR     R0, =0x11E1A300
para que el tiempo sea 300000000 = 5*60*1.000.000 es decir 5 minutos

Dicho y hecho. Parcheo la flash con el programa WSMP, la meto en el movil, y 
ahora el puerto infrarrojos se apaga si no hay datos tras 5 minutos, no tras 1 
minuto.

Totalmente orgulloso de mi mismo, hago un fichero de texto con el parche, le 
pongo una cabecera explicando como funciona, y lo preparo para publicarlo 
manana.
Tiempo total consumido: hora y media.

26/09 *********** Lunes ***********
Publico el parche de eliminar los mensajes innecesarios, y la respuesta es muy 
satisfactoria.
Creo que esperare un poco antes de seguir haciendo mas parches. La razon es 
que, mal que me pese, el SX1 es un modelo de mas de 3 anos, bastante caro, y no
se si hay mucha gente que lo use. Y es posible que simplemente haya pasado de 
moda. Visto de otro modo: ?quien hace actualmente programas para OS/2 ?

He conseguido extraer de los ficheros de cabecera  .h  todas las funciones 
exportadas, y las librerias en las que se encuentran.
Con esta lista hago un mega-programa que las invoca a todas, y averiguo en que 
posicion de la flash se encuentran.
Esto es equivalente a esos listados que circulan por ahi con las funciones 
exportadas en windows.dll
Lo bueno es que ahora puedo saber mas o menos las rutinas llamadas por otros 
programas, con lo que adquieren mayor sentido los desensamblados producidos por
IDA.

En total, unas 2.000 rutinas que me seran muy utiles.

27/09 *********** Martes ***********
Pues los parches tienen cierto exito. Sobre todo entre los usuarios que mas 
activos estan en el foro. Eso me anima a hacer mas.
Otra cosa que me fastidia es que, cuando quieres instalar una nueva aplicacion,
el movil pregunta demasiadas cosas:
1) Aviso de seguridad de instalacion: Imposible verificar proveedor. Continuar?
2) Instalar myApplication?
3) Opciones: Instalar/Ver certificado/Ver detalles
4) Sustituir x.yz por x.yz? (en caso de que ya este instalada)
5) Seleccione memoria: Mem. tel. / Tarj. m.
6) Instalacion completa

Esto es bastante engorroso, sobre todo cuando yo instalo mis propios programas.
El proceso incluye
A) editar mi programa
B) compilar
C) activar infrarrojos
D) transferirlo
E) instalarlo, respondiendo las preguntas 1-6 anteriores
F) probarlo

El paso C) mas o menos lo tengo apanado. El paso B) y D) los tengo 
automatizados con pulsaciones de teclas en el PC.
Pero si redujera el paso E), seria mas rapido de instalar.

La pregunta 1) se hace porque mi aplicacion no esta firmada.  He mirado en la 
web, y parece que un programador normal no puede firmar sus aplicaciones. Hace 
falta un certificado proporcionado por Symbian o Nokia, el cual no voy a 
solicitar.

Lo primero es averiguar cual es el programa que manda el mensaje. Empiezo la 
instalacion, y con ayuda del TaskSpy descubro que es InstEng.dll
Este programa tiene unas 300 subrutinas.
una de ellas llama a
CAknMessageQueryDialog::NewL
La cual se usa para mostrar un mensaje.
La primera idea que se me ocurre es no llamar a esta rutina. Grave error. 
Cuando lo pruebo, no aparece ningun mensaje en absoluto. Asi que no es posible 
responder "Si, quiero instalar esta aplicacion". Por eso la rutina que espera 
la respuesta nunca se llama, por lo que se queda esperando una respuesta que 
nunca sera capaz de recibir.

Veo que esta rutina es llamada a su vez por otras 5. Una de ellas debe de ser 
la que hay que eliminar.

Estudiando un poco aprendo que una aplicacion firmada incluye un flag en la 
cabecera del instalador.
Lo explicare mejor: un programa consiste siempre en un fichero de tipo *.app , 
ademas de otros ficheros extras, tales como otro con todos los dibujos (*.mbm),
otro para diferentes idiomas (*.r0x, *.rsc), uno con los iconos para el menu 
(*.aif), los sonidos (*.wav), ...
Todos estos se empaquetan en un instalador *.sis , que se puede firmar con un 
certificado.
El instalador mira si el  .sis  esta firmado, y luego si el certificado es 
valido.
Una de las caracteristicas del certificado es que el quinto byte es 0x04
Esto aparece unas 20 veces en el programa que instala aplicaciones. Solo 3 de 
ellas estan relacionadas con las rutinas encontradas antes, por lo que decido 
sustituir las 3 veces
MOV R0, #4
CMP R1, R0
BEQ loc_xxx

por
....
B loc_xxx

para que salte en todos los casos, aunque la validacion no sea cierta.
Ahora parece funcionar, y siempre aparece como firmado. Luego pruebo una por 
una, y encuentro la rutina que es correcta.

Ya se que no lo he explicado con mucho detalle, pero es que este es el 
tipico-tedioso proceso de encontrar la rutina adecuada. Es lo mismo que se 
hace para crackear programas de PC, de ZX-Spectrum, o de XBox.

Prosigo. La pregunta 4) aparece cuando quieres instalar la misma aplicacion 
que ya esta instalada. Cuando yo hago mis propios programas, la version es 
siempre la misma, por lo que la pregunta es correcta, aunque es inutil en mi 
caso, y me gustaria eliminarla.

Cada programa tiene una version consistente en 3 datos:
-Numero mayor de version, desde 0 hasta 127
-Numero menor, desde 0 hasta 99
-Numero de construccion, desde 0 hasta 32767
Es posible saber la version de un programa. A partir del UID, se carga; despues
se crea un objeto TVersion, y se usan los miembros iMajor, iMinor, iBuild

Esto se hace en InstEng.dll en las rutinas
505bd88c = MajorVersion()
505bd898 = MinorVersion()
la version de construccion (build) no se compara. Aunque sea superior, aparece 
como si fuera la misma.
Por lo tanto el parche es facil. Hago que MajorVersion() siempre devuelva 
127+1, asi el instalador siempre se creera que esta instalando una version 
superior y nunca preguntara.
Lo bueno es que, cuando esta instalado, aparece como la version correcta.
Solo engano al instalador en la comprobacion que se hace durante el proceso de 
instalacion.

Una solucion mas limpia seria simplemente eliminar el mensaje que informa de 
que las versiones son distintas, pero por ahora funciona.

Tras algunas pruebas mas, compruebo que funciona adecuadamente, y lo meto en un
fichero con una explicacion, listo para ser publicado.

*EOF*